package edu.joe.game;

import javax.media.opengl.GL2;

/**
 * Render the particle. TODO (billboarding)
 * 
 * @author Joe
 * 
 */
public class ParticleRenderer {

	public void render(GL2 gl, SceneCamera camera, ParticleData particle,
			ParticleGraphicsModel graphics) {
		gl.glPushMatrix();
		if (graphics.billboard) {
			// TODO calculate matrix to point particle at camera
			double[] mvm = new double[16];
			gl.glGetDoublev(GL2.GL_MODELVIEW_MATRIX, mvm, 0);
			double[] camUp = new double[3];
			double[] look = new double[3];
			double[] right = new double[3];
			double[] up = new double[3];
			// Get camera up vector
			// from
			// http://www.gamedev.net/topic/497918-eye-and-up-vectors-from-view-matrix/
			camUp[0] = mvm[1];
			camUp[1] = mvm[5];
			camUp[2] = mvm[9];
//			camUp[0] = 0;
//			camUp[1] = 1;
//			camUp[2] = 0;
			// Do billboarding
			// http://nehe.gamedev.net/article/billboarding_how_to/18011/
			look[0] = camera.camX - particle.x;
			look[1] = camera.camY - particle.y;
			look[2] = camera.camZ - particle.z;
			double lmag = 1.0/(Math.sqrt(look[0]*look[0] + look[1]*look[1] + look[2]*look[2]));
			look[0] *= lmag;
			look[1] *= lmag;
			look[2] *= lmag;
			right[0] = camUp[1] * look[2] - camUp[2] * look[1];
			right[1] = camUp[2] * look[0] - camUp[0] * look[2];
			right[2] = camUp[0] * look[1] - camUp[1] * look[0];
			up[0] = look[1] * right[2] - look[2] * right[1];
			up[1] = look[2] * right[0] - look[0] * right[2];
			up[2] = look[0] * right[1] - look[1] * right[0];

			mvm[0] = right[0];
			mvm[4] = up[0];
			mvm[8] = look[0];
			mvm[12] = particle.x;
			mvm[1] = right[1];
			mvm[5] = up[1];
			mvm[9] = look[1];
			mvm[13] = particle.y;
			mvm[2] = right[2];
			mvm[6] = up[2];
			mvm[10] = look[2];
			mvm[14] = particle.z;
			mvm[3] = mvm[7] = mvm[11] = 0;
			mvm[15] = 1;
			
			gl.glMultMatrixd(mvm, 0);
		}
		else {
			gl.glTranslated(particle.x, particle.y, particle.z);
			gl.glRotated(particle.ax, 1, 0, 0);
			gl.glRotated(particle.ay, 0, 1, 0);
			gl.glRotated(particle.az, 0, 0, 1);
		}

		gl.glBegin(GL2.GL_QUADS);
		gl.glColor4d(particle.r, particle.g, particle.b, particle.a);
		gl.glTexCoord2d(1.0, 1.0);
		gl.glVertex3d(-0.5 * particle.w, 0.5 * particle.h, 0);
		gl.glColor4d(particle.r, particle.g, particle.b, particle.a);
		gl.glTexCoord2d(0.0, 1.0);
		gl.glVertex3d(0.5 * particle.w, 0.5 * particle.h, 0);
		gl.glColor4d(particle.r, particle.g, particle.b, particle.a);
		gl.glTexCoord2d(0.0, 0.0);
		gl.glVertex3d(0.5 * particle.w, -0.5 * particle.h, 0);
		gl.glColor4d(particle.r, particle.g, particle.b, particle.a);
		gl.glTexCoord2d(1.0, 0.0);
		gl.glVertex3d(-0.5 * particle.w, -0.5 * particle.h, 0);
		gl.glEnd();
		gl.glPopMatrix();
	}
}
